package com.ruoyi.common.utils.keling;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.ruoyi.common.utils.file.FileUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.noear.snack.ONode;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;


public class KeLingUtil {

    static String ak = "a5302b5ae87f4e25bd529008bb9acf74"; // 填写access key
    static String sk = "01ee8f7ac2574127b46f26e6b316a7e1"; // 填写secret key

    private String token = null;
    private KeLingUtil _instance = null;

    public KeLingUtil getInstance() {
        if (null == _instance) {
            _instance = new KeLingUtil();
            token = _instance.sign(ak, sk);
        }
        return _instance;
    }

    public static void main(String[] args) {


//        KeLingUtil keLingUtil=   new KeLingUtil();
//        keLingUtil.getInstance();
//        KeLingRequest keLing = new KeLingRequest();
//        keLing.setPrompt("波普风格图片，主体是猫，背景设置纯白色，参考主体轮廓生成。采用明亮和大胆的色彩，使用鲜艳而强烈的颜色，重点是互补色对比。运用简洁的造型，主体运用大众化、商业化的题材，强调艺术与大众文化的紧密联系，反映了当代社会的消费文化和审美趋势。");
//        keLing.setImage("E:\\BaiduNetdiskDownload\\实物线稿\\Object_3k-line\\1_Natural\\1_Animals\\2_Cat\\swtp_00388_pop\\swtp_00388_pop.jpg");
//        keLing.setNumber(5);
//        keLing.setFidelity(0.5);
//        keLing.setNegativePrompt("worst quality, low quality, lowres, JPEG artifacts");
//       String taskId= keLingUtil.generations(keLing);
//        try {
//            Thread.sleep(10000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        Map<String, List<String>> resultMap = keLingUtil.queryByTaskId(taskId);
//        System.out.println(JSON.toJSONString(resultMap));
        String sourceFolder = "D:\\BaiduNetdiskDownload\\实物素描\\Object_3k\\1_Natural\\1_Animals\\4_Elephant";  // 源文
        moveAlreadyFiles(sourceFolder,"SM");
//        moveFiles(sourceFolder, "MH");
//        imageToGrayscale(sourceFolder);


    }


    private String sign(String ak, String sk) {
        try {
            Date expiredAt = new Date(System.currentTimeMillis() + 72000 * 1000); // 有效时间，此处示例代表当前时间+1800s(30min)
            Date notBefore = new Date(System.currentTimeMillis() - 5 * 1000); //开始生效的时间，此处示例代表当前时间-5秒
            Algorithm algo = Algorithm.HMAC256(sk);
            Map<String, Object> header = new HashMap<String, Object>();
            header.put("alg", "HS256");
            return JWT.create()
                    .withIssuer(ak)
                    .withHeader(header)
                    .withExpiresAt(expiredAt)
                    .withNotBefore(notBefore)
                    .sign(algo);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String convertImageToBase64(String imagePath) throws IOException {
        // 读取图片文件
        File file = new File(imagePath);
        FileInputStream fileInputStream = new FileInputStream(file);

        // 创建字节数组
        byte[] bytes = new byte[(int) file.length()];
        fileInputStream.read(bytes);
        fileInputStream.close();

        // 使用Base64编码
        return Base64.getEncoder().encodeToString(bytes);
    }

    public String generations(KeLingRequest req) {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            String apiUrl = "https://api.klingai.com/v1/images/generations";
            HttpPost post = new HttpPost(apiUrl);
            post.setHeader("Content-Type", "application/json");
            post.setHeader("Authorization", "Bearer " + token); // 替换为你的鉴权信息
            String imgBasee64 = convertImageToBase64(req.getImage());
            KeLing keLing = new KeLing();
            keLing.setModel("kling-v1");
            keLing.setPrompt(req.getPrompt());
            keLing.setN(req.getNumber());
            keLing.setImage_fidelity(req.getFidelity());
            keLing.setAspect_ratio("1:1");
            keLing.setImage(imgBasee64);
            keLing.setNegative_prompt(req.getNegativePrompt());
            String str = JSON.toJSONString(keLing);
            // 设置请求体
            post.setEntity(new StringEntity(str));
            // 发送请求并获取响应
            HttpResponse response = httpClient.execute(post);
            System.out.println("Response Code: " + response.getStatusLine().getStatusCode());
            String responseString = EntityUtils.toString(response.getEntity());
            System.out.println("Response Body: " + responseString);
            ONode oNode = ONode.load(responseString);
            Integer code = oNode.select("$.code").getInt();
            String nodeTaskId = null;
            if (code == 0) {
                nodeTaskId = oNode.select("$.data.task_id").getString();
            } else if (code == 1004) {
                KeLingUtil keLingUtil = new KeLingUtil();
                keLingUtil.getInstance();
                generations(req);
            } else if (code == 1102) {
                nodeTaskId = "欠费";
            }
            return nodeTaskId;
        } catch (IOException e) {
            System.out.println(e);

        }

        return null;
    }

    public Map<String, List<String>> queryByTaskId(String taskId) {
        Map<String, List<String>> resultMap = new HashMap<>();
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            String apiUrl = "https://api.klingai.com/v1/images/generations/" + taskId;
            HttpGet get = new HttpGet(apiUrl);
            get.setHeader("Content-Type", "application/json");
            get.setHeader("Authorization", "Bearer " + token);
            // 发送请求并获取响应
            HttpResponse response = httpClient.execute(get);
            System.out.println("Response Code: " + response.getStatusLine().getStatusCode());
            String responseString = EntityUtils.toString(response.getEntity());
            System.out.println("Response Body: " + responseString);
            ONode oNode = ONode.load(responseString);
            Integer code = oNode.select("$.code").getInt();
            String msg = oNode.select("$.message").getString();
            String taskStatus = oNode.select("$.data.task_status").getString();
            if (code == 0 && msg.equals("SUCCEED") && taskStatus.equals("succeed")) {
                try {
                    List<String> urls = new ArrayList<>();
                    // 获取所有 URL
                    List<String> images = oNode.select("$.data.task_result.images").toObject((new ArrayList<String>() {
                    }).getClass());
                    if (CollectionUtils.isNotEmpty(images)) {
                        for (int i = 0; i < images.size(); i++) {
                            ONode urlNode = ONode.load(images.get(i));
                            String url = urlNode.select("$.url").getString();
                            urls.add(url);
                        }
                    }
                    resultMap.put(taskId, urls);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            } else if (code == 1004) {
                KeLingUtil keLingUtil = new KeLingUtil();
                keLingUtil.getInstance();
                queryByTaskId(taskId);
            }
            return resultMap;

        } catch (IOException e) {
            System.out.println(e);

        }

        return resultMap;
    }

    public Map<String, List<String>> queryPage(int pageNum, int pageSize) {
        Map<String, List<String>> resultMap = new HashMap<>();
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            String apiUrl = "https://api.klingai.com//v1/images/generations?pageNum=" + pageNum + "&pageSize=" + pageSize;
            HttpGet get = new HttpGet(apiUrl);
            get.setHeader("Content-Type", "application/json");
            get.setHeader("Authorization", "Bearer " + token);
            // 发送请求并获取响应
            HttpResponse response = httpClient.execute(get);
            System.out.println("Response Code: " + response.getStatusLine().getStatusCode());
            String responseString = EntityUtils.toString(response.getEntity());
            System.out.println("Response Body: " + responseString);
            ONode oNode = ONode.load(responseString);
            Integer code = oNode.select("$.code").getInt();
            String msg = oNode.select("$.message").getString();

            if (code == 0 && msg.equals("SUCCEED")) {

                // 使用 fastjson 解析
                JSONObject jsonObject = JSONObject.parseObject(responseString);
                JSONArray dataArray = jsonObject.getJSONArray("data");

                for (int i = 0; i < dataArray.size(); i++) {
                    JSONObject item = dataArray.getJSONObject(i);
                    String taskId = item.getString("task_id");
                    // 获取图片 URL 列表
                    JSONArray imagesArray = item.getJSONObject("task_result").getJSONArray("images");
                    List<String> urls = new ArrayList<>();
                    if (imagesArray != null) {
                        for (int j = 0; j < imagesArray.size(); j++) {
                            String url = imagesArray.getJSONObject(j).getString("url");
                            urls.add(url);
                        }
                        resultMap.put(taskId, urls);
                    }
                }

            } else if (code == 1004) {
                KeLingUtil keLingUtil = new KeLingUtil();
                keLingUtil.getInstance();
                queryPage(pageNum, pageSize);
            }
            return resultMap;

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    public static void downloadImage(String imageUrl, String saveDir, String baseFileName, String fileExtension) {

        String path = "";
        try {
            // 创建文件夹
            File directory = new File(saveDir);
            if (!directory.exists()) {
                directory.mkdirs();
            }

            // 确定文件名
            String fileName = baseFileName + fileExtension;
            File file = new File(directory, fileName);
            int counter = 1;

            while (file.exists()) {
                fileName = baseFileName + "_" + counter + fileExtension;
                file = new File(directory, fileName);
                counter++;
            }

            // 创建 URL 对象
            URL url = new URL(imageUrl);
            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setRequestMethod("GET");
            httpConn.setConnectTimeout(10000);
            httpConn.setReadTimeout(10000);

            // 检查响应码
            if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                // 输入流
                InputStream inputStream = httpConn.getInputStream();
                // 输出流
                FileOutputStream outputStream = new FileOutputStream(file);

                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }

                outputStream.close();
                inputStream.close();
                System.out.println("图片下载成功: " + file.getAbsolutePath());
                path = file.getAbsolutePath();
            } else {
                System.out.println("无效的响应代码: " + httpConn.getResponseCode());
            }
            httpConn.disconnect();
        } catch (IOException e) {
            System.out.println("报错下载链接：" + path);
            e.printStackTrace();
        }
    }

    public static void menuMakingMoveFiles(String sourceFolderPath, String type) {
        Path sourceFolder = Paths.get(sourceFolderPath);  // 源文件夹路径
        // 目标文件夹路径

        try {
            Files.walk(sourceFolder)
                    .filter(Files::isRegularFile)
                    .forEach(path -> {
                        String name = FileUtils.getNameNotSuffix(path.toString());
                        String targetFolder = path.getParent() + "\\" + name + "_" + type;
//                        String targetFolder = path.getParent()+"\\"+ FileUtils.getNameNotSuffix(path.toString())+"_"+type;
                        System.out.println(targetFolder);
                        moveFile(path, Paths.get(targetFolder));

                    });

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void moveFiles(String sourceFolderPath, String type) {
        Path sourceFolder = Paths.get(sourceFolderPath);  // 源文件夹路径
        // 目标文件夹路径

        try {
            Files.walk(sourceFolder)
                    .filter(Files::isRegularFile)
                    .forEach(path -> {
                        String name = FileUtils.getNameNotSuffix(path.toString());
                        if(name.contains("la")){
                            String[] laNames = name.split("_");

                            String laName = laNames[0] + "_" + laNames[1];
                            String targetFolder = path.getParent() + "\\" + laName + "_" + type;
//                        String targetFolder = path.getParent()+"\\"+ FileUtils.getNameNotSuffix(path.toString())+"_"+type;
                            System.out.println(targetFolder);
                            moveFile(path, Paths.get(targetFolder));
                        }

                    });

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void moveAlreadyFiles(String sourceFolderPath, String type) {
        Path sourceFolder = Paths.get(sourceFolderPath);  // 源文件夹路径
        // 目标文件夹路径

        try {
            Files.walk(sourceFolder)
                    .filter(Files::isRegularFile)
                    .forEach(path -> {
                        String folderName = path.toString().substring(0, path.toString().indexOf(type) + 2);
                        String targetFolder = folderName;
                        System.out.println(targetFolder);
                        moveFile(path, Paths.get(targetFolder));

                    });

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void moveFile(Path file, Path targetFolder) {
        // 检查目标文件夹是否存在
        if (!Files.exists(targetFolder) || !Files.isDirectory(targetFolder)) {
            System.out.println("目标文件夹不存在，跳过文件: " + file);
            return;
        }

        try {
            // 移动文件到目标文件夹
            Files.move(file, targetFolder.resolve(file.getFileName()), StandardCopyOption.ATOMIC_MOVE);
            System.out.println("文件已移动到目标文件夹: " + file.getFileName());
        } catch (IOException e) {
            System.out.println("移动文件时出错: " + file + " - " + e.getMessage());
        }
    }

    private static void imageToGrayscale(String sourcePath) {
        try {
            Path sourceFolder = Paths.get(sourcePath);  // 源文件夹路
            Files.walk(sourceFolder)
                    .filter(Files::isRegularFile)
                    .forEach(path -> {
                        // 读取彩色图片
                        File inputFile = new File(path.toString());
                        BufferedImage colorImage = null;
                        try {
                            colorImage = ImageIO.read(inputFile);
                        } catch (IOException e) {

                            throw new RuntimeException(e);
                        }

                        // 创建一个新的图像，大小与原图相同
                        BufferedImage selectiveGrayImage = new BufferedImage(
                                colorImage.getWidth(), colorImage.getHeight(),
                                BufferedImage.TYPE_INT_RGB
                        );

                        // 遍历每个像素，将彩色像素转换为灰度
                        for (int x = 0; x < colorImage.getWidth(); x++) {
                            for (int y = 0; y < colorImage.getHeight(); y++) {
                                int rgb = colorImage.getRGB(x, y);

                                // 获取RGB通道
                                int r = (rgb >> 16) & 0xff;
                                int g = (rgb >> 8) & 0xff;
                                int b = rgb & 0xff;

                                // 判断是否为“彩色”像素，可以使用饱和度或色彩差异
                                // 这里用简单的阈值判断：RGB三个通道差值超过某个值则认为是彩色
                                int colorDifferenceThreshold = 3; // 阈值，可调整
                                boolean isColor = Math.abs(r - g) > colorDifferenceThreshold ||
                                        Math.abs(r - b) > colorDifferenceThreshold ||
                                        Math.abs(g - b) > colorDifferenceThreshold;

                                if (isColor) {
                                    // 将彩色像素转换为灰度
                                    int grayLevel = (int) (0.3 * r + 0.59 * g + 0.11 * b);
                                    int grayRgb = (grayLevel << 16) | (grayLevel << 8) | grayLevel;
                                    selectiveGrayImage.setRGB(x, y, grayRgb);
                                } else {
                                    // 保留原始灰度像素
                                    selectiveGrayImage.setRGB(x, y, rgb);
                                }
                            }
                        }
                        // 保存灰度图像
                        File outputFile = new File(path.toString());
                        try {
                            ImageIO.write(selectiveGrayImage, "jpg", outputFile);
                            System.out.println("转换完成，灰度图片已保存到：" + path.toString());
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    });


        } catch (IOException e) {
            System.out.println("读取或写入图片时发生错误：" + e.getMessage());
        }
    }

}
